package ee.homework.eighth;

/**
 * Matrix multiplication
 * 
 * @author Kaarel Hanson
 */
public class MatrixMultiplication {

	public static void main(String[] args) {
		new MatrixMultiplication().run();
	}

	public void run() {
		int[][] matrix = new int[][] { 
				{ 0, 1, 0, 0, 0 }, 
				{ 0, 0, 0, 1, 1 },
				{ 1, 0, 0, 0, 0 }, 
				{ 1, 0, 0, 0, 1 }, 
				{ 0, 0, 0, 0, 0 } 
		};

		System.out.println("Matrix");
		print(matrix);

		int result2Hops[][] = multiply(matrix, matrix);
		System.out.println("Two hops");
		print(result2Hops);

		int result3Hops[][] = multiply(result2Hops, matrix);
		System.out.println("Three hops");
		print(result3Hops);

		int[][] firstMultip = multiply(setDiagonal(matrix), matrix);
		System.out.println("First Multiplication");
		print(firstMultip);
		int[][] secondMultip = multiply(setDiagonal(firstMultip), matrix);
		System.out.println("Second Multiplication");
		print(secondMultip);
		int[][] thirdMultip = multiply(setDiagonal(secondMultip), matrix);

		System.out.println("Transitive closure");
		print(thirdMultip);
	}

	public void print(int[][] matrix) {
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[0].length; j++) {
				System.out.print(" " + matrix[i][j]);
			}
			System.out.println();
		}
		System.out.println();
	}

	public int[][] multiply(int[][] matrixA, int[][] matrixB) {
		int[][] resultMatrix = new int[matrixA.length][matrixB[0].length];

		for (int i = 0; i < matrixA.length; i++) {
			for (int j = 0; j < matrixB[0].length; j++) {
				for (int k = 0; k < matrixA[0].length; k++) {
					if (matrixA[i][k] * matrixB[k][j] > 0) {
						resultMatrix[i][j] = matrixA[i][k] * matrixB[k][j];
					}
				}
			}
		}
		return resultMatrix;
	}

	public int[][] setDiagonal(int[][] matrix) {
		int[][] result = new int[matrix.length][matrix[0].length];
		for (int i = 0; i < result.length; i++) {
			for (int j = 0; j < result.length; j++) {
				if (i == j) {
					result[i][j] = 1;
				} else {
					result[i][j] = matrix[i][j];
				}
			}
		}
		return result;
	}

}
